<template>
  <Modal
    v-model:active="solverTaskModelVueActive"
    transfer
    title="求解任务"
    :width="580"
  >
    <Scroll :height="600" use-y-bar>
      <ConfigProvider :props="providedProps">
        <Form ref="form" :model="formModel" style="padding: 24px">
          <Column :span="24">
            <div class="title">
              <div class="title_color"></div>
              <div class="title_content">基础信息</div>
            </div>
          </Column>
          <Column :span="21" :offset="3">
            <FormItem
              label="名称:"
              prop="name"
              :rules="{ required: true, message: '请输入名称' }"
            >
              <Input
                v-model:value="formModel.name"
                placeholder="请输入名称"
              ></Input>
            </FormItem>
          </Column>
          <Column :span="21" :offset="3">
            <FormItem
              label="求解器选择:"
              prop="solverId"
              :rules="{ required: true, message: '请选择求解器' }"
            >
              <Select
                v-model:value="formModel.solverId"
                :options="selectTypeOptions"
                placeholder="请选择求解器"
                @change="onSolverChange"
              ></Select>
            </FormItem>
          </Column>
          <Divider></Divider>
          <Column :span="24">
            <div class="title">
              <div class="title_color"></div>
              <div class="title_content">容器内文件下载/上传</div>
            </div>
          </Column>
          <Column v-if="fileParamdownloadList.length > 0">
            <FormItem
              label="下载至容器:"
              style="margin-bottom: 8px; margin-top: 16px"
            >
            </FormItem>
            <Table
              :columns="downloadListColumns"
              :data="fileParamdownloadList"
              highlight
              ref="table"
            >
              <TableColumn name="源文件" id-key="value" :order="0">
                <template #default="{ row }">
                  <Input v-model:value="row.value">
                    <template #after-action>
                      <ButtonGroup>
                        <Button
                          :icon="CloudArrowUp"
                          @click="openImportFileModal(row)"
                        >
                        </Button>
                        <Upload
                          accept=".bdf"
                          :multiple="true"
                          @change="
                            (file) => {
                              handleChange(file, row);
                            }
                          "
                          manual
                          @success="handleSuccess"
                          button-label=" "
                          hidden-files
                        ></Upload>
                      </ButtonGroup>
                    </template>
                  </Input>
                </template>
              </TableColumn>
            </Table>
          </Column>
          <Column v-if="fileParamuploadList.length > 0">
            <FormItem
              label="从容器上传至云端:"
              style="margin-bottom: 8px; margin-top: 16px"
            >
            </FormItem>
            <Table
              :columns="uploadListColumns"
              :data="fileParamuploadList"
              highlight
              ref="table"
            >
              <TableColumn name="目标地址" id-key="value" :order="1">
                <template #default="{ row }">
                  <Input v-model:value="row.value">
                    <template #after-action>
                      <Button
                        :icon="CloudArrowUp"
                        @click="openOutputFileModal(row)"
                      >
                      </Button>
                    </template>
                  </Input>
                </template>
              </TableColumn>
            </Table>
          </Column>
          <!-- <Column :span="21" :offset="3">
            <FormItem label="输入文件:" prop="inputType">
              <RadioGroup v-model:value="formModel.inputType">
                <Radio key="本地上传" label="本地上传"> 本地上传 </Radio>
                <Radio key="从云存储选择" label="从云存储选择">
                  从云存储选择
                </Radio>
              </RadioGroup>
            </FormItem>
          </Column>
          <Column
            :span="21"
            :offset="3"
            v-if="formModel.inputType === '本地上传'"
          >
            <Upload
              accept=".bdf"
              :multiple="true"
              @change="handleChange"
              manual
              @success="handleSuccess"
            ></Upload
            >支持拓展名：bdf
          </Column>
          <Column
            :span="24"
            :offset="0"
            v-if="formModel.inputType === '从云存储选择'"
          >
            <FormItem prop="inputPath" label=" ">
              <Input v-model:value="formModel.inputPath" disabled>
                <template #after-action>
                  <Button type="primary" @click="openImportFileModal">
                    选择…
                  </Button>
                </template>
              </Input>
            </FormItem>
          </Column>
          <Column :span="21" :offset="3">
            <FormItem label="输出地址:" prop="output">
              <Input v-model:value="formModel.output" disabled>
                <template #after-action>
                  <Button type="primary" @click="openOutputFileModal">
                    选择…
                  </Button>
                </template>
              </Input>
            </FormItem>
          </Column> -->
          <Divider></Divider>
          <Column :span="24">
            <div class="title">
              <div class="title_color"></div>
              <div class="title_content">资源限制</div>
            </div>
          </Column>
          <Row :gap="[0, 16]" style="width: 100%">
            <Column :span="9" :offset="3">
              <FormItem label="CPU:" prop="cpu">
                <NumberInput
                  v-model:value="formModel.cpu"
                  :min="0"
                  style="width: 100px"
                />
              </FormItem>
            </Column>
            <Column :span="9" :offset="3">
              <FormItem label="内存:" prop="memory">
                <NumberInput
                  v-model:value="formModel.memory"
                  :min="0"
                  style="width: 100px"
                />
              </FormItem>
            </Column>
          </Row>
          <Divider></Divider>
          <Column :span="24">
            <div class="title">
              <div class="title_color"></div>
              <div class="title_content">启动命令</div>
            </div>
          </Column>
          <Table
            :columns="cmdColumns"
            :data="cmdParamList"
            highlight
            ref="table2"
          >
            <TableColumn name="值" id-key="value" :order="2">
              <template #default="{ row }">
                <Input
                  v-model:value="formModel[row.param]"
                  :disabled="!row.editable"
                  @change="getCommandPreview"
                >
                </Input>
              </template>
            </TableColumn>
          </Table>
          <!-- <Column
            :span="21"
            :offset="3"
            v-for="item in cmdParamList"
            :key="item.param"
          >
            <FormItem :label="item.nameCN + ':'" :prop="item.param">
              <Input
                v-model:value="formModel[item.param]"
                :placeholder="`请输入${item.nameCN}`"
                @change="getCommandPreview"
              >
                <template #before v-if="item.type === 'file'">
                  {{ getFileParamName(item.fileParamName) }}
                </template>
              </Input>
            </FormItem>
          </Column> -->
          <Column :span="21" :offset="3">
            <FormItem label="命令预览:">
              {{ command }}
            </FormItem>
          </Column>
          <Divider></Divider>
          <Column :span="24">
            <div class="title">
              <div class="title_color"></div>
              <div class="title_content">环境变量</div>
            </div>
          </Column>
          <Table :columns="envColumns" :data="envList" highlight ref="table3">
            <TableColumn name="值" id-key="value" :order="2">
              <template #default="{ row }">
                <Input v-model:value="row.value" :disabled="!row.editable">
                </Input>
              </template>
            </TableColumn>
          </Table>
        </Form>
      </ConfigProvider>
    </Scroll>
    <ImportFileModal :onSuccess="onSuccess"></ImportFileModal>
    <OutputFileModal :onSuccess="onSuccessOutput"></OutputFileModal>
    <template #footer>
      <Button type="default" @click="handleCancel">取消</Button>
      <Button type="primary" @click="onConfirm">运行</Button>
    </template>
  </Modal>
</template>
<script setup lang="ts">
import { ref, reactive, onMounted } from "vue";
import {
  Modal,
  Select,
  Divider,
  FormItem,
  ConfigProvider,
  Checkbox,
  Row,
  Column,
  Input,
  RadioGroup,
  Radio,
  Upload,
  Button,
  NumberInput,
  Message,
  Form,
  Scroll,
  Table,
  TableColumn,
  ButtonGroup,
  defineTableColumns,
} from "cax-ui";
import { MagnifyingGlass, CloudArrowDown, CloudArrowUp } from "@vexip-ui/icons";
import { storeToRefs } from "pinia";
import { useCoreStore } from "@/UI/store";
import { useSolverStore } from "@/UI/store/solverStore";
import ImportFileModal from "./ImportFileModal.vue";
import OutputFileModal from "./OutputFileModal.vue";
import { createTask, getSolverList, uploadFile } from "@/UI/api/solver";
const coreStore = useCoreStore();
const solverStore = useSolverStore();
const form = ref<InstanceType<typeof Form>>();

let { solverTaskModelVueActive } = storeToRefs(useCoreStore());
const providedProps = {
  default: { clearable: true },
  formItem: { required: false },
};
const importFileModalVisible = ref(false);
const ImportCloudModalVisible = ref(false);
const formModel = reactive({
  name: "",
  inputType: "从云存储选择",
  inputPath: "",
  output: "",
  solverId: undefined,
  cpu: 0,
  memory: 0,
});
const selectTypeOptions = ref([]);
const solverList = ref([]);
const cmdParamList = ref([]);
const fileParamList = ref([]);
const envList = ref([]);
const editRow = ref({});
const fileParamuploadList = ref([]);
const fileParamdownloadList = ref([]);
const command = ref("");
const fileList = ref();
const cmdColumns = reactive(
  defineTableColumns([
    {
      name: "名称",
      key: "param",
    },
    {
      name: "描述",
      key: "nameCN",
    },
  ])
);
const uploadListColumns = reactive(
  defineTableColumns([
    {
      name: "容器内文件地址",
      key: "path",
    },
  ])
);
const downloadListColumns = reactive(
  defineTableColumns([
    {
      name: "容器内目标地址",
      key: "path",
    },
  ])
);
const envColumns = reactive(
  defineTableColumns([
    {
      name: "名称",
      key: "name",
    },
    {
      name: "描述",
      key: "description",
    },
  ])
);

onMounted(() => {
  getSolverList().then((res) => {
    if (res.code === 200) {
      if (res.data?.records?.length) {
        solverList.value = res.data.records;
      } else {
        solverList.value = [];
      }
      selectTypeOptions.value = (res.data?.records || []).map((item) => ({
        label: item.name,
        value: item.id,
      }));
    } else {
      selectTypeOptions.value = [];
    }
  });
});

const handleChange = (files: any, row) => {
  // console.log(files);
  // console.log(files[0]);
  const file = files[0];
  const filename = file.name;
  // console.log(filename);
  const formData = new FormData();
  formData.append(
    "file",
    new window.File([file], filename, { type: file.type })
  );
  formData.append("bucket", import.meta.env.VITE_OSS_SOLVER_BUCKET);
  formData.append("path", "studio/");
  formData.append("objectName", filename);
  uploadFile(formData).then((res) => {
    if (res.code === 200) {
      Message.success("上传成功");
      row.value = `oss://${
        import.meta.env.VITE_OSS_SOLVER_BUCKET
      }/studio/${filename}`;
    }
  });
  fileList.value = files;
};

const handleSuccess = (res: any) => {
  // console.log("handleSuccess", res);
};

const onSolverChange = (value: any) => {
  const solver = solverList.value.find((item: any) => item.id === value);
  if (solver) {
    const fileParamList = solver?.fileParamList || [];
    formModel.cpu = solver?.cpuLimit;
    formModel.memory = solver?.memoryLimit;
    cmdParamList.value = solver?.cmdParamList || [];
    fileParamList.value = fileParamList;
    envList.value = solver?.envList || [];
    let _fileParamuploadList: any[] = [];
    let _fileParamdownloadList: any[] = [];
    fileParamList.forEach((item: any) => {
      if (item.type === "upload") {
        _fileParamuploadList.push(item);
      }
      if (item.type === "download") {
        _fileParamdownloadList.push(item);
      }
    });
    fileParamuploadList.value = _fileParamuploadList;
    fileParamdownloadList.value = _fileParamdownloadList;
    // command.value = solver.cmd;
    let _command = solver.cmd;
    if (cmdParamList.value.length) {
      cmdParamList.value.forEach((item: any) => {
        if (item.defaultValue) {
          formModel[item.param] = item.defaultValue;
        } else {
          formModel[item.param] = "";
        }
      });
    }
    getCommandPreview();
  }
};

const openImportFileModal = (row: any) => {
  editRow.value = row;
  coreStore.setImportFileModalVueActive(true);
};
const openImportCloudModal = (row: any) => {
  editRow.value = row;
  coreStore.setImportCloudFileModalVueActive(true);
};
const openOutputFileModal = (row: any) => {
  editRow.value = row;
  coreStore.setOutputFileModalVueActive(true);
};
const onSuccess = (data: any) => {
  editRow.value = { ...editRow.value, value: data.name };
  const newArr = fileParamdownloadList.value.map((item: any) => {
    if (item.name === editRow.value.name) {
      return {
        ...item,
        value: data.name,
      };
    }
    return item;
  });
  fileParamdownloadList.value = newArr;
  // formModel.inputPath = data.name;
};
const onSuccessOutput = (data: any) => {
  editRow.value = { ...editRow.value, value: data.name };
  const newArr = fileParamuploadList.value.map((item: any) => {
    if (item.name === editRow.value.name) {
      return {
        ...item,
        value: data.name,
      };
    }
    return item;
  });
  fileParamuploadList.value = newArr;
  // formModel.output = data.name;
};

const getCommandPreview = () => {
  const _solverId = formModel.solverId;
  const solver = solverList.value.find((item: any) => item.id === _solverId);
  if (!solver) {
    command.value = "";
    return;
  }
  let _command = solver.cmd;
  if (cmdParamList.value.length) {
    cmdParamList.value.forEach((item: any) => {
      if (formModel[item.param]) {
        _command += ` ${item.param} ${formModel[item.param]}`;
      }
    });
  }
  command.value = _command;
};

const getFileParamName = (fileParamName: string) => {
  const fileParam = fileParamList.value.find(
    (item: any) => item.name === fileParamName
  );
  if (fileParam) {
    return `${fileParam.path}/`;
  }
  return "";
};

async function onConfirm() {
  const errors = await form.value?.validate();

  if (errors.length) {
    Message.error("表单验证不通过");
    return false;
  } else {
    coreStore.setSolverResultName(formModel.name);
    const options: any[] = [];
    const uploadList: any[] = [];
    const downloadList: any[] = [];
    const envs: any[] = [];
    let uploadLocalPath = "";
    let downloadLocalPath = "";
    if (fileParamuploadList.value.length) {
      fileParamuploadList.value.forEach((item: any) => {
        uploadList.push({
          ossPath: item.value.replace("oss://sh-dc/", ""),
          localPath: item.path,
        });
      });
    }
    if (fileParamdownloadList.value.length) {
      const pattern = /\.[^.]+$/;
      fileParamdownloadList.value.forEach((item: any) => {
        console.log("fileParamdownloadList item", item);
        downloadList.push({
          ossPath: item.value.replace("oss://sh-dc/", ""), // TODO 先写死
          localPath: item.path,
          isDir: pattern.test(item.value) ? "false" : "true",
        });
      });
    }
    if (envList.value.length) {
      envList.value.forEach((item: any) => {
        envs.push({
          name: item.name,
          value: item.value,
        });
      });
    }
    if (cmdParamList.value.length) {
      let requireAllHaveValue = true;
      let errorParam = true;
      cmdParamList.value.forEach((item: any) => {
        if (item.required && !formModel[item.param]) {
          requireAllHaveValue = false;
          errorParam = item.param;
        }
        if (formModel[item.param]) {
          options.push({
            key: item.param,
            value: formModel[item.param],
          });
        }
        // if (item.type === "file") {
        //   const fileParam = fileParamList.value.find(
        //     (_fileParam: any) => _fileParam.name === item.fileParamName
        //   );
        //   if (fileParam.type === "download") {
        //     downloadLocalPath = `${fileParam.path}/${
        //       formModel[item.param] || ""
        //     }`;
        //   }
        //   if (fileParam.type === "upload") {
        //     uploadLocalPath = `${fileParam.path}/${
        //       formModel[item.param] || ""
        //     }`;
        //   }
        //   options.push({
        //     key: item.param,
        //     value: `${fileParam.path}/${formModel[item.param] || ""}`,
        //   });
        // } else {
        //   if (formModel[item.param]) {
        //     options.push({
        //       key: item.param,
        //       value: formModel[item.param],
        //     });
        //   }
        // }
      });
      if (!requireAllHaveValue) {
        Message.error(`${errorParam}为必填项，请填写`);
        return;
      }
    }
    // uploadList: [
    //   {
    //     ossPath: formModel.output,
    //     localPath: uploadLocalPath,
    //   },
    // ],
    // downloadList: [
    //   {
    //     ossPath: formModel.inputPath,
    //     localPath: downloadLocalPath,
    //     isDir: "true",
    //   },
    // ],
    console.log({
      name: formModel.name,
      uploadList: uploadList,
      downloadList: downloadList,
      solverId: `${formModel.solverId}`,
      resourceCPU: formModel.cpu,
      resourceMEM: formModel.memory,
      options: options,
      envs: envs,
    });
    createTask({
      name: formModel.name,
      uploadList: uploadList,
      downloadList: downloadList,
      solverId: `${formModel.solverId}`,
      resourceCPU: formModel.cpu,
      resourceMEM: formModel.memory,
      options: options,
      envs: envs,
    })
      .then((res) => {
        coreStore.setSolverResultId(res.data.taskID);
        coreStore.setSolverResultModelVueActive(true);
        coreStore.setSolverTaskModelVueActive(false);
        solverStore.putSolverTaskList({
          taskId: res.data.taskID,
          taskName: formModel.name,
        });
      })
      .catch((err) => {
        console.log(err);
      });
  }
  return false;
}
function handleCancel() {
  coreStore.setSolverTaskModelVueActive(false);
  resetFormModel();
}
const resetFormModel = () => {
  formModel.name = "";
  formModel.inputType = "从云存储选择"; // 根据实际需求初始化
  formModel.inputPath = "";
  formModel.output = "";
  formModel.solverId = undefined;
  formModel.cpu = 0;
  formModel.memory = 0;
  cmdParamList.value.forEach((item: any) => {
    formModel[item.param] = undefined;
  });
  cmdParamList.value = [];
  fileParamList.value = [];
  command.value = "";
  fileList.value = [];
};
</script>

<style scoped lang="less">
.title {
  display: flex;
  align-items: center;
  margin-bottom: 16px;

  .title_color {
    width: 4px;
    height: 12px;
    background: #339af0;
    margin-right: 8px;
  }
  .title_content {
    opacity: 1;
    font-family: PingFang SC;
    font-size: 14px;
    font-weight: 600;
    line-height: 22px;
    letter-spacing: 0em;
    font-variation-settings: "opsz" auto;
    /* content/主要一级primary */
    /* 样式描述：--vxp-content-color-primary */
    color: #212529;
  }
}

:deep(.vxp-input--after) {
  width: 100px !important;
}
</style>
